/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package rpt.lib;

import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionListener;
import java.util.Enumeration;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JTabbedPane;
import javax.swing.JTree;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import rpt.bd.cenario.CTabPainelBd;

/**
 *
 * @author Roberto
 */
public class CArvoreMenu {

    CControleNavegacaoMenuArvoreTab fNavegador = null;
    ChangeListener fOuvinteMudancaTab = null;
    JMenuBar fBarraMenu = null;
    JTree fArvore = null;
    JTabbedPane fPainelTabPrincipal = null;

    public CArvoreMenu(JMenuBar aBarraMenu, JTree aArvore, JTabbedPane aPainelTabPrincipal) {
        fBarraMenu = aBarraMenu;
        fArvore = aArvore;
        fPainelTabPrincipal = aPainelTabPrincipal;
        fNavegador = new CControleNavegacaoMenuArvoreTab(aArvore, aPainelTabPrincipal);
        adicionarOuvinteTabPrincipal(fPainelTabPrincipal);
        preparar();
        expandAll(fArvore, true, 0, 1);
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    // If expand is true, expands all nodes in the tree.
    // Otherwise, collapses all nodes in the tree.
    final public void expandAll(JTree tree, boolean expand, int aNivel, Integer aNivelMaximo) {
        TreeNode root = (TreeNode) tree.getModel().getRoot();
        // Traverse tree from root
        if (aNivel < aNivelMaximo) {
            expandAll(tree, new TreePath(root), expand, aNivel + 1, aNivelMaximo);
        }
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    private void expandAll(JTree tree, TreePath parent, boolean expand, int aNivel, Integer aNivelMaximo) {
        // Traverse children
        TreeNode node = (TreeNode) parent.getLastPathComponent();
        if (node.getChildCount() >= 0) {
            for (Enumeration e = node.children(); e.hasMoreElements();) {
                TreeNode n = (TreeNode) e.nextElement();
                TreePath path = parent.pathByAddingChild(n);
                if (aNivel < aNivelMaximo) {
                    expandAll(tree, path, expand, aNivel + 1, aNivelMaximo);
                }
            }
        }

        // Expansion or collapse must be done bottom-up
        if (expand) {
            tree.expandPath(parent);
        } else {
            tree.collapsePath(parent);
        }
    }

    protected void prepararMenu(Object aObjetoMenu) {

        int vNumItens = 0;
        Component[] vComponentes = null;

        if (aObjetoMenu instanceof JMenuBar) {
            JMenuBar mb = (JMenuBar) aObjetoMenu;
            Container c = mb.getParent();
            vNumItens = mb.getComponentCount();
            vComponentes = mb.getComponents();
        } else if (aObjetoMenu instanceof JMenu) {
            JMenu m = (JMenu) aObjetoMenu;
            Container c = m.getParent();
            vNumItens = m.getMenuComponentCount();
            vComponentes = ((JMenu) aObjetoMenu).getMenuComponents();
        } else {
            if (aObjetoMenu instanceof JMenuItem) {
                JMenuItem mi = (JMenuItem) aObjetoMenu;
                String s = mi.getText();
                if ((s == null) || (s.equals(""))) {
                    vNumItens = 0;
                } else {
                    if (s.substring(0, 1).equals("*")) {
                        Container c = mi.getParent();
                        if (c instanceof JPopupMenu) {
                            JPopupMenu pm = (JPopupMenu) c;
                            pm.remove(mi);
                        }
                        vNumItens = 0;
                    } else {
                        vNumItens = mi.getComponentCount();
                        vComponentes = mi.getComponents();
                    }
                }
            } else {
                vNumItens = 0;
            }
        }

        if (vNumItens == 0) {
            return;
        }

        for (int vContador = 0; vContador < vNumItens; vContador++) {
            Component c = vComponentes[vContador];
            if (c instanceof JMenuItem) {
                prepararMenu((JMenuItem) c);
            }
        }
    }

    protected void prepararArvoreMenu(
            DefaultMutableTreeNode aTreeNodePai,
            Object aObjetoMenu) {

        int vNumItens = 0;
        Component[] vComponentes = null;

        if (aObjetoMenu instanceof JMenuBar) {
            JMenuBar mb = (JMenuBar) aObjetoMenu;
            vNumItens = mb.getComponentCount();
            vComponentes = mb.getComponents();
        } else if (aObjetoMenu instanceof JMenu) {
            JMenu m = (JMenu) aObjetoMenu;
            vNumItens = m.getMenuComponentCount();
            vComponentes = ((JMenu) aObjetoMenu).getMenuComponents();
        } else if (aObjetoMenu instanceof JMenuItem) {
            JMenuItem mi = (JMenuItem) aObjetoMenu;
            vNumItens = mi.getComponentCount();
            vComponentes = mi.getComponents();
        } else {
            vNumItens = 0;
        }

        if (vNumItens == 0) {
            return;
        }

        Component vComponente = null;
        String vTexto = null;
        DefaultMutableTreeNode vTreeNodeFilho = null;

        for (int vContador = 0; vContador < vNumItens; vContador++) {
            vComponente = vComponentes[vContador];
            if (vComponente instanceof JMenuItem) {
                JMenuItem j = (JMenuItem) vComponente;
                vTreeNodeFilho = new DefaultMutableTreeNode(new CAdaptadorMenu(vComponente));
                aTreeNodePai.add(vTreeNodeFilho);
                fNavegador.adicionar(vComponente, vTreeNodeFilho);
                prepararArvoreMenu(vTreeNodeFilho, vComponente);
            }
        }
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    private class CAdaptadorMenu {

        Object fObjetoMenu;

        public CAdaptadorMenu(Object aObjetoMenu) {
            super();
            fObjetoMenu = aObjetoMenu;
        }

        @Override
        public String toString() {
            return getText();
        }

        public Object getObjetoMenu() {
            return fObjetoMenu;
        }

        public String getText() {
            if (fObjetoMenu instanceof JMenuBar) {
                return ((JMenuItem) fObjetoMenu).getText();
            } else if (fObjetoMenu instanceof JMenu) {
                return ((JMenu) fObjetoMenu).getText();
            } else if (fObjetoMenu instanceof JMenuItem) {
                return ((JMenuItem) fObjetoMenu).getText();
            }
            return "???";
        }
    }

    /**
     * 
     * @return 
     */
    public ChangeListener getOuvinteMudancaTab() {
        if (fOuvinteMudancaTab == null) {
            fOuvinteMudancaTab =
                    new ChangeListener() {
                        //Vector fMenus = new Vector();
                        // This method is called whenever the selected tab changes

                        @Override
                        public void stateChanged(ChangeEvent evt) {
                            JTabbedPane pane = (JTabbedPane) evt.getSource();
                            // Get current tab
                            int sel = pane.getSelectedIndex();
                            Component c = pane.getTabComponentAt(sel);
                            if (c instanceof CTabBotaoFechar) {
                                fNavegador.focarTodosTab(pane, (CTabBotaoFechar) c);
                            }
                            System.err.println("Mudou tab!");
                        }
                    };
        }
        return fOuvinteMudancaTab;
    }

    final private void preparar() {

        DefaultMutableTreeNode treeNode1 = new DefaultMutableTreeNode("SIN");
        fArvore.setModel(new DefaultTreeModel(treeNode1));
        prepararMenu(fBarraMenu);
        prepararArvoreMenu(treeNode1, fBarraMenu);

        fArvore.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION);

        //Listen for when the selection changes.
        fArvore.addTreeSelectionListener(
                new TreeSelectionListener() {

                    @Override
                    public void valueChanged(TreeSelectionEvent e) {
                        DefaultMutableTreeNode node =
                                (DefaultMutableTreeNode) fArvore.getLastSelectedPathComponent();
                        if (node == null) {
                            return;
                        }
                        Object nodeInfo = node.getUserObject();
                        if (nodeInfo != null) {
                            CAdaptadorMenu am = (CAdaptadorMenu) nodeInfo;
                            Object om = am.getObjetoMenu();
                            if (om instanceof JMenuItem) {
                                CRegistroControleNavegacaoMenuArvoreTab rcn = fNavegador.getMenu(om);
                                if (rcn != null) {
                                    rcn.focarTodos();
                                }
                                ActionListener[] al = ((JMenuItem) om).getActionListeners();
                                al[0].actionPerformed(null);
                            }
                        }
                    }
                });
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    private void adicionarOuvinteTabPrincipal(JTabbedPane aTabbedPane) {
        aTabbedPane.addChangeListener(
                new ChangeListener() {
                    //Vector fMenus = new Vector();
                    // This method is called whenever the selected tab changes

                    @Override
                    public void stateChanged(ChangeEvent evt) {
                        JTabbedPane pane = (JTabbedPane) evt.getSource();
                        // Get current tab
                        int sel = pane.getSelectedIndex();
                        Component c = pane.getTabComponentAt(sel);
                        if (c instanceof CTabBotaoFechar) {
                            fNavegador.focarTodosTab(pane, (CTabBotaoFechar) c);
                        }
                    }
                });
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    public int indiceTab(Component aComponente) {
        int vIndice = -1;
        CRegistroControleNavegacaoMenuArvoreTab cnmat = fNavegador.getMenu(aComponente);
        if (cnmat != null) {
            CTabBotaoFechar tbf = cnmat.getTabBotaoFechar();
            int vIndAux = vIndice = fNavegador.getIndiceTab(fPainelTabPrincipal, tbf);
            if (vIndAux >= 0) {
                vIndice = vIndAux;
            }
            /*
            CRegistroControleNavegacaoMenuArvoreTab cnmat2 = fNavegador.getTab(swTpnPrincipal, tbf);
            if (cnmat2 != null) {
            vIndice = fNavegador.getIndiceTab(swTpnPrincipal, tbf);
            }
             *
             */
        }
        /*
        int vNum = swTpnPrincipal.getTabCount();
        boolean vAchou = false;
        for (int vContador = 0; (!vAchou) && (vContador < vNum); vContador++) {
        Component c = swTpnPrincipal.getTabComponentAt(vContador);
        if (c == aComponente) {
        vAchou = true;
        vIndice = vContador;
        }
        }
         */
        return vIndice;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    public JTabbedPane prepararTab(String aTitulo, JMenuItem aItemMenu, JTabbedPane aTabPanel) {
        JTabbedPane vPainel = new CTabPainelBd(); // JTabbedPane();
        aTabPanel.add(aTitulo, vPainel);
        CTabBotaoFechar tbf = initTabComponent(aTabPanel.getTabCount() - 1);
        fNavegador.setTabRegistroControle(aItemMenu, aTabPanel, tbf);
        return vPainel;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    public JTabbedPane prepararTab(String aTitulo, JMenuItem aItemMenu) {
        JTabbedPane vPainel = prepararTab(aTitulo, aItemMenu, fPainelTabPrincipal);
        /*
        JTabbedPane vPainel = new JTabbedPane();
        fPainelTabPrincipal.add(aTitulo,vPainel);
        CTabBotaoFechar tbf = initTabComponent(fPainelTabPrincipal.getTabCount()-1);
        fNavegador.setTabRegistroControle(aItemMenu,fPainelTabPrincipal,tbf);
         */
        return vPainel;
    }

    /**************************************************************************/
    /***                                                                    ***/
    /**************************************************************************/
    private CTabBotaoFechar initTabComponent(int i) {
        CTabBotaoFechar btc = new CTabBotaoFechar(fPainelTabPrincipal);
        fPainelTabPrincipal.setTabComponentAt(i, btc);
        return btc;
    }

    public void focarTodosMenu(Object aObjetoMenu) {
        fNavegador.focarTodosMenu(aObjetoMenu);
    }
}
